﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Globalization;

namespace System.Windows.Media.Media3D10
{
    /// <summary>
    /// Converti un <see cref="System.String"/> en <see cref="SlimDX.Vector3"/>, et inversement
    /// </summary>
    public class Vector3TypeConverter : TypeConverter
    {
        /// <summary>
        /// Retourne une valeur indiquant si ce convertisseur peut convertir un objet du type donné en objet du type de ce convertisseur, à l'aide du contexte spécifié. 
        /// </summary>
        /// <param name="context"><see cref="ITypeDescriptorContext"/> qui fournit un contexte de format.</param>
        /// <param name="sourceType"><see cref="System.Type"/> représentant le type à partir duquel effectuer la conversion. </param>
        /// <returns>true si ce convertisseur peut effectuer la conversion ; sinon, false.</returns>
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return (sourceType == typeof(string));
        }

        /// <summary>
        /// Retourne une valeur indiquant si ce convertisseur peut convertir l'objet en objet du type spécifié, à l'aide du contexte déterminé. 
        /// </summary>
        /// <param name="context"><see cref="ITypeDescriptorContext"/> qui fournit un contexte de format.</param>
        /// <param name="destinationType"><see cref="System.Type"/> représentant le type vers lequel effectuer la conversion. </param>
        /// <returns>true si ce convertisseur peut effectuer la conversion ; sinon, false. </returns>
        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return (destinationType == typeof(string));
        }

        /// <summary>
        /// Convertit l'objet donné en objet du type de ce convertisseur, à l'aide du contexte et des informations de culture spécifiés. 
        /// </summary>
        /// <param name="context"><see cref="ITypeDescriptorContext"/> qui fournit un contexte de format.</param>
        /// <param name="culture"><see cref="CultureInfo"/> à utiliser comme culture en cours.</param>
        /// <param name="value"><see cref="System.Object"/> à convertir.</param>
        /// <returns><see cref="System.Object"/> représentant la valeur convertie. </returns>
        public override object ConvertFrom(ITypeDescriptorContext context, Globalization.CultureInfo culture, object value)
        {
            if (object.ReferenceEquals(value, null))
                throw new ArgumentNullException("value");
            var values = value.ToString().Split(new char[] { ' ', ',' });
            if (values.Length != 3)
                throw new InvalidCastException("Specified value is invalid");
            float x;
            float y;
            float z;
            if (!float.TryParse(values[0], out x) || !float.TryParse(values[1], out y) || !float.TryParse(values[2], out z))
                throw new InvalidCastException("Specified value is invalid");
            return new SlimDX.Vector3(x, y, z);
        }

        /// <summary>
        /// Convertit l'objet donné en objet du type de ce convertisseur, à l'aide du contexte et des informations de culture spécifiés. 
        /// </summary>
        /// <param name="context"><see cref="ITypeDescriptorContext"/> qui fournit un contexte de format.</param>
        /// <param name="culture">><see cref="CultureInfo"/>. Si référence Null (Nothing en Visual Basic) est passée, la culture est supposée être celle en cours.</param>
        /// <param name="value"><see cref="System.Object"/> à convertir.</param>
        /// <param name="destinationType">Type auquel le paramètre value doit être converti. </param>
        /// <returns><see cref="System.Object"/> représentant la valeur convertie. </returns>
        public override object ConvertTo(ITypeDescriptorContext context, Globalization.CultureInfo culture, object value, Type destinationType)
        {
            SlimDX.Vector3 vector = (SlimDX.Vector3)value;
            if (object.ReferenceEquals(vector, null))
                throw new InvalidCastException("Specified value is invalid");
            return string.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", new object[] { vector.X, vector.Y, vector.Z });
        }
    }
}
